package chian_to_chain

import (
	"chain_bridge_service/configs"
	"chain_bridge_service/internal/repository/mongodb/chain_config"
	"chain_bridge_service/internal/repository/mongodb/chain_token"
	"context"
	"github.com/pkg/errors"
	"go.mongodb.org/mongo-driver/bson"
	"go.mongodb.org/mongo-driver/bson/primitive"
	"go.mongodb.org/mongo-driver/mongo"
)

func NewModel() *ChainToChain {
	return new(ChainToChain)
}

func (c *ChainToChain) List(client *mongo.Client, pageIndex uint, pageSize uint) ([]ChainToChain, error) {
	var list []ChainToChain
	//skip := int64((pageIndex - 1) * pageSize)
	//findOptions := options.Find()
	//findOptions.SetSort(bson.D{{"_id", -1}})
	//findOptions.SetSkip(skip)
	//findOptions.SetLimit(int64(pageSize))
	cfg := configs.Get().Mongodb
	keyClient := client.Database(cfg.Config.Name).Collection("chain_to_chain")
	//objId, _ := primitive.ObjectIDFromHex(c.Id)

	find, err := keyClient.Find(context.TODO(), bson.M{"userId": c.UserId})
	if err != nil {
		return nil, err
	}
	err = find.All(context.TODO(), &list)
	return list, nil
}
func (c *ChainToChain) Find(client *mongo.Client) ([]chain_config.ChainConfig, error) {
	var list []chain_config.ChainConfig
	cfg := configs.Get().Mongodb
	keyClient := client.Database(cfg.Config.Name).Collection("chain_config")
	objId, _ := primitive.ObjectIDFromHex(c.ChainConfigId0)
	objId1, _ := primitive.ObjectIDFromHex(c.ChainConfigId1)
	filter := bson.D{
		{"$or", bson.A{
			bson.D{{"_id", objId}},
			bson.D{{"_id", objId1}},
			// 可以添加更多的条件
		}},
	}
	find, err := keyClient.Find(context.TODO(), filter)
	err = find.All(context.TODO(), &list)
	return list, err
}
func (c *ChainToChain) FindToken(client *mongo.Client) ([]chain_token.ChainToken, error) {
	var list []chain_token.ChainToken
	cfg := configs.Get().Mongodb
	keyClient := client.Database(cfg.Config.Name).Collection("chain_token")
	objId, _ := primitive.ObjectIDFromHex(c.Token0)
	objId1, _ := primitive.ObjectIDFromHex(c.Token1)
	filter := bson.D{
		{"$or", bson.A{
			bson.D{{"_id", objId}},
			bson.D{{"_id", objId1}},
			// 可以添加更多的条件
		}},
	}
	find, err := keyClient.Find(context.TODO(), filter)
	err = find.All(context.TODO(), &list)
	return list, err
}

func (c *ChainToChain) Create(client *mongo.Client) error {
	cfg := configs.Get().Mongodb
	keyClient := client.Database(cfg.Config.Name).Collection("chain_to_chain")
	_, err := keyClient.InsertOne(context.TODO(), c)
	return err
}

func (c *ChainToChain) Update(client *mongo.Client) (err error) {
	cfg := configs.Get().Mongodb
	keyClient := client.Database(cfg.Config.Name).Collection("chain_to_chain")
	objId, _ := primitive.ObjectIDFromHex(c.Id)
	filter := bson.M{"_id": objId}
	update := bson.M{}
	if c.ChainConfigId0 != "" {
		update["chainConfigId0"] = c.ChainConfigId0

	}
	if c.ChainConfigId1 != "" {
		update["chainConfigId1"] = c.ChainConfigId1
	}
	if c.Token0 != "" {
		update["token0"] = c.Token0
	}
	if c.Token1 != "" {
		update["token1"] = c.Token1
	}
	if !c.Rate.IsZero() {
		update["rate"] = c.Rate
	}

	_, err = keyClient.UpdateOne(context.TODO(), filter, bson.M{"$set": update})
	return err
}

func (c *ChainToChain) Count(db *mongo.Client) (count int64, err error) {
	cfg := configs.Get().Mongodb
	client := db.Database(cfg.Config.Name).Collection("chain_to_chain")
	count, err = client.CountDocuments(context.TODO(), bson.D{{"userId", c.UserId}})
	if err != nil && !errors.Is(err, mongo.ErrNoDocuments) {
		return 0, err
	}
	return count, nil
}

func (c *ChainToChain) Delete(client *mongo.Client) (err error) {
	cfg := configs.Get().Mongodb
	keyClient := client.Database(cfg.Config.Name).Collection("chain_to_chain")
	objId, _ := primitive.ObjectIDFromHex(c.Id)
	_, err = keyClient.DeleteOne(context.TODO(), bson.M{"_id": objId})
	return err
}

func (c *ChainToChain) ApiList(client *mongo.Client, userId string) ([]bson.M, error) {
	var list []bson.M
	cfg := configs.Get().Mongodb
	keyClient := client.Database(cfg.Config.Name).Collection("chain_to_chain")
	find, err := keyClient.Find(context.TODO(), bson.D{{"userId", userId}})
	if err != nil {
		return nil, err
	}
	err = find.All(context.TODO(), &list)
	return list, nil
}

func (c *ChainToChain) FindOne(client *mongo.Client) (ChainToChain, error) {

	var data ChainToChain
	cfg := configs.Get().Mongodb
	chainClient := client.Database(cfg.Config.Name).Collection("chain_to_chain")
	filter := bson.M{"chainConfigId0": c.ChainConfigId0, "chainConfigId1": c.ChainConfigId1, "userId": c.UserId, "token0": c.Token0, "token1": c.Token1}
	err := chainClient.FindOne(context.TODO(), filter).Decode(&data)
	return data, err
}

func (c *ChainToChain) GetCountByParams(client *mongo.Client) (int64, error) {
	cfg := configs.Get().Mongodb
	chainClient := client.Database(cfg.Config.Name).Collection("chain_to_chain")
	//使用反射机制
	//v := reflect.ValueOf(*c)
	//typeOfC := v.Type()
	//for i := 0; i < v.NumField(); i++ {
	//	fieldName := typeOfC.Field(i).Name
	//	fieldValue := v.Field(i).Interface()
	//	filter[fieldName] = fieldValue
	//}
	filter := bson.M{
		"userId": c.UserId,
		"$or": []bson.M{
			{"chainConfigId0": c.ChainConfigId0},
			{"chainConfigId1": c.ChainConfigId1},
		},
	}

	count, err := chainClient.CountDocuments(context.TODO(), filter)
	return count, err
}
